/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * MortgageCorePane2.java
 *
 * Created on Jun 1, 2009, 11:08:27 PM
 */

package viewer.mortgage;

/**
 *
 * @author Steve Noble
 */


import javax.swing.*;
import java.awt.event.MouseEvent;
import java.awt.Point;
import java.util.*;
import java.io.*;

import java.awt.Color;

import MortgageCore.*;
import Household.Household;
import Bank.Bank;
import grapher.MetricViewer;
import viewer.common.Trans2D;
import simframe.simulation.Metric;
import simframe.simulation.SwarmMetric;

public class MortgageCorePane extends javax.swing.JPanel {

    final static Color[] colors = new Color[]{Color.BLUE, Color.RED, Color.GREEN, Color.ORANGE, Color.PINK, Color.MAGENTA,
    Color.gray, Color.CYAN, Color.YELLOW
    };

    public MortgageCorePane(SavingsSim sim) {
        this(sim, geography.Geography.MinLongitude,
                geography.Geography.MinLatitude,
                geography.Geography.MaxLongitude,
                 geography.Geography.MaxLatitude);

//        this.newZoomWindowCheckBox.setEnabled(false);
//        this.newZoomWindowCheckBox.setSelected(true);

        this.bankSummaryButton.setVisible(true);
        //zoomButton.setVisible(false);
        //newZoomWindowCheckBox.setVisible(false);
        setToolBarSateObjectMap(true);
    }

    public void setToolBarSateObjectMap(boolean isObjectMap) {
        this.showHomeownersCheckbox.setEnabled(isObjectMap);
        this.showBanksCheckbox.setEnabled(isObjectMap);
        this.showRentersCheckbox.setEnabled(isObjectMap);
        this.showHomeownersCheckbox.setVisible(isObjectMap);
        this.showBanksCheckbox.setVisible(isObjectMap);
        this.showRentersCheckbox.setVisible(isObjectMap);
    }
    
    /** Creates new form MortgageCorePane2 */
    public MortgageCorePane(SavingsSim sim, double x0, double y0, double x1, double y1) {
        initComponents();

        ss = sim;

        // SavingsSim sim
        myCanvas = new MortgageCoreView(ss); // , x0, y0, x1, y1);

        mapPanel.add(myCanvas);

        ss.addViewer(myCanvas, 7);

        myCanvas.reset();

        //myCanvas.setBounds(0, 0, kWorldWidth, kWorldHeight);
        //
        // metrics
        //
        grapher = new MetricViewer();

        // grapher.setBounds(metricPanel.getBounds());
        sim.addMetricDisplay(grapher);

        graphPanel.add(grapher);

        //this.newZoomWindowCheckBox.setEnabled(true);
        //this.newZoomWindowCheckBox.setSelected(false);
          this.bankSummaryButton.setVisible(false);

        addMetrics(new ArrayList<String>());
    }




    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        mapGroup = new javax.swing.ButtonGroup();
        zoomGroup = new javax.swing.ButtonGroup();
        hhMetrics = new javax.swing.ButtonGroup();
        toolBar = new javax.swing.JToolBar();
        objectMapButton = new javax.swing.JRadioButton();
        bubbleMapButton = new javax.swing.JRadioButton();
        jSeparator2 = new javax.swing.JToolBar.Separator();
        bankSummaryButton = new javax.swing.JButton();
        jSeparator1 = new javax.swing.JToolBar.Separator();
        zoomOutButton = new javax.swing.JButton();
        zoomInButton = new javax.swing.JButton();
        jSeparator3 = new javax.swing.JToolBar.Separator();
        showHomeownersCheckbox = new javax.swing.JCheckBox();
        showRentersCheckbox = new javax.swing.JCheckBox();
        showBanksCheckbox = new javax.swing.JCheckBox();
        jPanel1 = new javax.swing.JPanel();
        metricPanel = new javax.swing.JPanel();
        mapPanel = new javax.swing.JPanel();
        graphPanel = new javax.swing.JPanel();

        setLayout(new java.awt.BorderLayout());

        toolBar.setBorder(null);
        toolBar.setFloatable(false);
        toolBar.setRollover(true);
        toolBar.setFont(new java.awt.Font("Lucida Grande", 0, 11));
        toolBar.setPreferredSize(new java.awt.Dimension(100, 25));

        mapGroup.add(objectMapButton);
        objectMapButton.setSelected(true);
        objectMapButton.setText("Object Map");
        objectMapButton.setFocusable(false);
        objectMapButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                objectMapButtonActionPerformed(evt);
            }
        });
        toolBar.add(objectMapButton);

        mapGroup.add(bubbleMapButton);
        bubbleMapButton.setText("Bubble Map");
        bubbleMapButton.setFocusable(false);
        bubbleMapButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                bubbleMapButtonActionPerformed(evt);
            }
        });
        toolBar.add(bubbleMapButton);
        toolBar.add(jSeparator2);

        bankSummaryButton.setText("Bank Summary");
        bankSummaryButton.setToolTipText("Summary Panel of Bank Information");
        bankSummaryButton.setBorder(javax.swing.BorderFactory.createBevelBorder(javax.swing.border.BevelBorder.RAISED));
        bankSummaryButton.setFocusable(false);
        bankSummaryButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        bankSummaryButton.setMaximumSize(new java.awt.Dimension(100, 18));
        bankSummaryButton.setMinimumSize(new java.awt.Dimension(100, 18));
        bankSummaryButton.setPreferredSize(new java.awt.Dimension(100, 18));
        bankSummaryButton.setRolloverEnabled(true);
        bankSummaryButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        bankSummaryButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                bankSummaryButtonActionPerformed(evt);
            }
        });
        toolBar.add(bankSummaryButton);
        toolBar.add(jSeparator1);

        zoomOutButton.setText("Zoom Out");
        zoomOutButton.setBorder(javax.swing.BorderFactory.createBevelBorder(javax.swing.border.BevelBorder.RAISED));
        zoomOutButton.setFocusable(false);
        zoomOutButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        zoomOutButton.setMaximumSize(new java.awt.Dimension(80, 18));
        zoomOutButton.setMinimumSize(new java.awt.Dimension(80, 18));
        zoomOutButton.setPreferredSize(new java.awt.Dimension(80, 18));
        zoomOutButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        zoomOutButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                zoomOutButtonActionPerformed(evt);
            }
        });
        toolBar.add(zoomOutButton);

        zoomInButton.setText("Zoom In");
        zoomInButton.setBorder(javax.swing.BorderFactory.createBevelBorder(javax.swing.border.BevelBorder.RAISED));
        zoomInButton.setFocusable(false);
        zoomInButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        zoomInButton.setMaximumSize(new java.awt.Dimension(80, 18));
        zoomInButton.setMinimumSize(new java.awt.Dimension(80, 18));
        zoomInButton.setPreferredSize(new java.awt.Dimension(80, 18));
        zoomInButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        zoomInButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                zoomInButtonActionPerformed(evt);
            }
        });
        toolBar.add(zoomInButton);
        toolBar.add(jSeparator3);

        showHomeownersCheckbox.setSelected(true);
        showHomeownersCheckbox.setText("Homeowners");
        showHomeownersCheckbox.setFocusable(false);
        showHomeownersCheckbox.setHorizontalTextPosition(javax.swing.SwingConstants.RIGHT);
        showHomeownersCheckbox.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                showHomeownersCheckboxActionPerformed(evt);
            }
        });
        toolBar.add(showHomeownersCheckbox);

        showRentersCheckbox.setSelected(true);
        showRentersCheckbox.setText("Renters");
        showRentersCheckbox.setFocusable(false);
        showRentersCheckbox.setHorizontalTextPosition(javax.swing.SwingConstants.RIGHT);
        showRentersCheckbox.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                showRentersCheckboxActionPerformed(evt);
            }
        });
        toolBar.add(showRentersCheckbox);

        showBanksCheckbox.setSelected(true);
        showBanksCheckbox.setText("Banks");
        showBanksCheckbox.setFocusable(false);
        showBanksCheckbox.setHorizontalTextPosition(javax.swing.SwingConstants.RIGHT);
        showBanksCheckbox.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                showBanksCheckboxActionPerformed(evt);
            }
        });
        toolBar.add(showBanksCheckbox);

        add(toolBar, java.awt.BorderLayout.NORTH);

        jPanel1.setBackground(new java.awt.Color(255, 255, 255));
        jPanel1.setLayout(new java.awt.BorderLayout());

        metricPanel.setBackground(new java.awt.Color(255, 255, 255));
        metricPanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Metrics"));
        metricPanel.setPreferredSize(new java.awt.Dimension(200, 294));
        metricPanel.setLayout(new javax.swing.BoxLayout(metricPanel, javax.swing.BoxLayout.PAGE_AXIS));
        jPanel1.add(metricPanel, java.awt.BorderLayout.WEST);

        mapPanel.setBackground(new java.awt.Color(0, 204, 255));
        mapPanel.setAutoscrolls(true);
        mapPanel.setLayout(new java.awt.BorderLayout());
        jPanel1.add(mapPanel, java.awt.BorderLayout.CENTER);

        add(jPanel1, java.awt.BorderLayout.CENTER);

        graphPanel.setBackground(new java.awt.Color(255, 255, 255));
        graphPanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Time Series"));
        graphPanel.setMinimumSize(new java.awt.Dimension(0, 200));
        graphPanel.setPreferredSize(new java.awt.Dimension(577, 200));
        graphPanel.setLayout(new java.awt.BorderLayout());
        add(graphPanel, java.awt.BorderLayout.SOUTH);
    }// </editor-fold>//GEN-END:initComponents


    private void windowClosing() {
        ss.removeViewer(myCanvas);
        ss.removeMetricDisplay(grapher);
    }


    private void addMetrics(List<String> defaultOn){

        int index = 0;


        JLabel hhMetricsLabel = new JLabel("Households");

        metricPanel.add(hhMetricsLabel);
        
        for(final SwarmMetric<Household> hhMetric : Household.getMetrics()) {
            // create Metric
            final Metric metric = ss.households.createSwarmMetric(hhMetric);
            
           grapher.addMetric(metric);
           myCanvas.addMetric(hhMetric);
           final Color col = colors[index % colors.length];

            final javax.swing.JCheckBox box = new javax.swing.JCheckBox(metric.getName());

            // hhMetrics.add(box);
            box.setBackground(java.awt.Color.WHITE);

            if (defaultOn.contains(metric.getName())) {
                box.setSelected(true);
                grapher.addDisplay(metric.getName(), col);
                myCanvas.addDisplay(hhMetric, col);
            }

            // TODO: set tooltip based on  a metric description

            box.addActionListener(new java.awt.event.ActionListener() {

                public void actionPerformed(java.awt.event.ActionEvent evt) {
                    hhMetricBoxChecked(box, hhMetric, col, evt);
                }
            });

            metricPanel.add(box);
            index++;
        }

         metricPanel.add(javax.swing.Box.createRigidArea(new java.awt.Dimension(0,20)));
         JLabel bankMetrics = new JLabel("Banks");

        metricPanel.add(bankMetrics);

          for(final SwarmMetric<Bank> bankMetric : Bank.getMetrics()) {
            // create Metric
            final Metric metric = ss.banks.createSwarmMetric(bankMetric);

           grapher.addMetric(metric);
           final Color col = colors[index % colors.length];

            final javax.swing.JCheckBox box = new javax.swing.JCheckBox(metric.getName());

            // hhMetrics.add(box);
            box.setBackground(java.awt.Color.WHITE);

            if (defaultOn.contains(metric.getName())) {
                box.setSelected(true);
                grapher.addDisplay(metric.getName(), col);
            }

            // TODO: set tooltip based on  a metric description

            box.addActionListener(new java.awt.event.ActionListener() {

                public void actionPerformed(java.awt.event.ActionEvent evt) {
                    bankMetricBoxChecked(box, bankMetric, col, evt);
                }
            });

            metricPanel.add(box);
            index++;
        }

        JButton PrintToFile = new JButton("Save to File");
        PrintToFile.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                PrintToFileActionPerformed(evt);
            }
        });
        metricPanel.add(PrintToFile);
    }

    private void PrintToFileActionPerformed(java.awt.event.ActionEvent evt)
    {
        grapher.printMetricsToFile();
    }

    private void hhMetricBoxChecked(javax.swing.JCheckBox box, SwarmMetric<Household> metric, Color col, java.awt.event.ActionEvent evt) {
        // TODO add your handling code here:
        if (box.getSelectedObjects() != null) {
            // add metric to grapher
            grapher.addDisplay(metric.getName(), col);
            myCanvas.addDisplay(metric, col);
            grapher.repaint();
            myCanvas.repaint();
        } else {
            // remove metric from grpaher
            grapher.removeDisplay(metric.getName());
            myCanvas.removeDisplay(metric);
            grapher.repaint();
            myCanvas.repaint();
        }
    }

    private void bankMetricBoxChecked(javax.swing.JCheckBox box, SwarmMetric<Bank> metric, Color col, java.awt.event.ActionEvent evt) {
        // TODO add your handling code here:
        if (box.getSelectedObjects() != null) {
            // add metric to grapher
            grapher.addDisplay(metric.getName(), col);
            grapher.repaint();
        } else {
            // remove metric from grpaher
            grapher.removeDisplay(metric.getName());
            grapher.repaint();
        }
    }

    private void objectMapButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_objectMapButtonActionPerformed
        changeMapMode();
}//GEN-LAST:event_objectMapButtonActionPerformed

    private void bubbleMapButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bubbleMapButtonActionPerformed
        changeMapMode();
}//GEN-LAST:event_bubbleMapButtonActionPerformed

    private void changeMapMode() {

        if (objectMapButton.getSelectedObjects() != null) {
            myCanvas.setMapMode(MortgageCoreView.MapMode.Object);
            setToolBarSateObjectMap(true);
        }
        else {
             myCanvas.setMapMode(MortgageCoreView.MapMode.Bubble);
             setToolBarSateObjectMap(false);
        }

        myCanvas.repaint();
    }
      // <editor-fold desc="Zoom Code">
    private int initX;
    private int initY;
    private Point initP;
    private java.awt.event.MouseListener[] miceListeners;

   java.awt.event.MouseAdapter waitForIt = new java.awt.event.MouseAdapter() {
            @Override
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                initialClick(evt);
            }
        };

    java.awt.event.MouseAdapter finalClick = new java.awt.event.MouseAdapter() {

        @Override
        public void mouseClicked(java.awt.event.MouseEvent evt) {
            finalClick(evt);
        }
    };

      java.awt.event.MouseMotionAdapter mouseMoved = new java.awt.event.MouseMotionAdapter() {

        @Override
          public void mouseMoved(MouseEvent e) {
              mouseHasMoved(e);
          }
      };

    private void mouseHasMoved(java.awt.event.MouseEvent evt) {
       int x = evt.getPoint().x;
       int y = evt.getPoint().y;

       // draw rubber band
   
       myCanvas.setRubberBand(initP.x, initP.y, x - initP.x, y - initP.y);

       myCanvas.repaint();
    }

    private void initialClick(java.awt.event.MouseEvent evt) {

        initP = evt.getPoint();

        // p = myCanvas.trans.invMap(p);
        
        JPopupMenu popup = new JPopupMenu();
        JMenuItem menuItem = new JMenuItem("Select bottom right corner");
        popup.add(menuItem);
        popup.setVisible(true);
        popup.show(myCanvas, initX - 50, initY - 40);
        myCanvas.removeMouseListener(waitForIt);
        myCanvas.addMouseMotionListener(mouseMoved);
        myCanvas.addMouseListener(finalClick);

    }

    private void finalClick(java.awt.event.MouseEvent evt) {
          Point finalP = evt.getPoint();

       // p = myCanvas.trans.invMap(p);

        myCanvas.clearRubberBand();

        myCanvas.removeMouseListener(finalClick);
        myCanvas.removeMouseMotionListener(mouseMoved);

        for (java.awt.event.MouseListener mouseL : miceListeners) {
            myCanvas.addMouseListener(mouseL);
        }

        myCanvas.repaint();

        // transform initial and final into coordinates
        Trans2D.Vec2D v = myCanvas.trans.invMap(initP);
        Trans2D.Vec2D w = myCanvas.trans.invMap(finalP);

        if (false) { //(newZoomWindowCheckBox.getSelectedObjects() != null) {

            final MortgageCorePane newView = new MortgageCorePane(ss, v.x, v.y, w.x, w.y);

            javax.swing.JFrame newSimFrame = new javax.swing.JFrame();

            newSimFrame.setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);

            newSimFrame.addWindowListener(new java.awt.event.WindowAdapter() {

                @Override
                public void windowClosing(java.awt.event.WindowEvent evt) {

                    newView.windowClosing();
                }
            });

            newSimFrame.add(newView);
            java.awt.Dimension d = new java.awt.Dimension(1200, 1000);

            newSimFrame.setSize(d);

            newSimFrame.setVisible(true);
        } else {
            myCanvas.updateTrans2D(v.x, v.y, w.x, w.y);

           myCanvas.reset();

            myCanvas.repaint();

           // List<String> metrics = new ArrayList<String>();

//            for(Metric metric : grapher.getMetricsOnDisplay()) {
//                metrics.add(metric.getName());
//            }
            
         //   grapher.clearMetrics();
          //  metricPanel.removeAll();

          //  addMetrics(metrics);
            
        //    metricPanel.revalidate();
            
        }
    }
    
    private void bankSummaryButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bankSummaryButtonActionPerformed

        if (bs == null) {
            bs = new BankSummary(ss);
            ss.addViewer(bs, 30);
        }

        bs.setVisible(true);

    }//GEN-LAST:event_bankSummaryButtonActionPerformed

    private void zoomInButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_zoomInButtonActionPerformed

        myCanvas.zoom(1.25);
        myCanvas.repaint();
}//GEN-LAST:event_zoomInButtonActionPerformed

    private void zoomOutButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_zoomOutButtonActionPerformed
        myCanvas.zoom(0.8);
        myCanvas.repaint();
}//GEN-LAST:event_zoomOutButtonActionPerformed

    private void showHomeownersCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_showHomeownersCheckboxActionPerformed
        myCanvas.setDrawHomowners(showHomeownersCheckbox.isSelected());
        myCanvas.repaint();
}//GEN-LAST:event_showHomeownersCheckboxActionPerformed

    private void showRentersCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_showRentersCheckboxActionPerformed
        myCanvas.setDrawRenters(showRentersCheckbox.isSelected());
        myCanvas.repaint();
    }//GEN-LAST:event_showRentersCheckboxActionPerformed

    private void showBanksCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_showBanksCheckboxActionPerformed
        myCanvas.setDrawBanks(showBanksCheckbox.isSelected());
        myCanvas.repaint();
    }//GEN-LAST:event_showBanksCheckboxActionPerformed

     // </editor-fold>

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton bankSummaryButton;
    private javax.swing.JRadioButton bubbleMapButton;
    private javax.swing.JPanel graphPanel;
    private javax.swing.ButtonGroup hhMetrics;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JToolBar.Separator jSeparator1;
    private javax.swing.JToolBar.Separator jSeparator2;
    private javax.swing.JToolBar.Separator jSeparator3;
    private javax.swing.ButtonGroup mapGroup;
    private javax.swing.JPanel mapPanel;
    private javax.swing.JPanel metricPanel;
    private javax.swing.JRadioButton objectMapButton;
    private javax.swing.JCheckBox showBanksCheckbox;
    private javax.swing.JCheckBox showHomeownersCheckbox;
    private javax.swing.JCheckBox showRentersCheckbox;
    private javax.swing.JToolBar toolBar;
    private javax.swing.ButtonGroup zoomGroup;
    private javax.swing.JButton zoomInButton;
    private javax.swing.JButton zoomOutButton;
    // End of variables declaration//GEN-END:variables


    private void viewHousesStateChange(java.awt.event.ItemEvent evt) {
        if (evt.getStateChange() == java.awt.event.ItemEvent.SELECTED) {
            myCanvas.showHomes(true);
        } else if (evt.getStateChange() == java.awt.event.ItemEvent.DESELECTED) {
            myCanvas.showHomes(false);
        }

        myCanvas.repaint();
    }


     // private state variables
    final private SavingsSim ss;
    final private MortgageCoreView myCanvas;
    final private MetricViewer grapher;
    private BankSummary bs = null;
    
}
